#!/usr/bin/env python3
template = """\
10CLEAR10,&H{sym[Start-1].u:X}:BLOAD"{filename}"
20DEFFNS(A)=PEEK(A)+256*(PEEK(A)>127)
30DEFFNW(A)=PEEK(A)+256*PEEK(A+1)
40DEFUSR=&H{sym[Start].u:X}
50A=USR(0)
60B=FNW({sym[CycFrm1]})+65536*PEEK({sym[CycFrm3]})
70SCREEN0
80?"Cyc,Err"B;A
90?"ACK "FNS({sym[AckTiming]})FNS({sym[AckTiming+1]})FNS({sym[AckTiming+2]})FNS({sym[AckTiming+3]})
"""
fnames = {'cas':'CAS:VDPtst', 'dsk':'vdptest.bin'}

import sys, re

class Val(object):
  def __init__(self, n):
    self.u = n & 0xFFFF
    self.s = self.u if self.u < 32768 else self.u - 65536
  def __str__(self):
    return str(self.s)  # return the signed one
  pass

def main():
  if len(sys.argv) < 2 or sys.argv[1].lower() not in fnames:
    sys.stderr.write("Usage: python3 loadertpl.py {cas|dsk}\n")

  parsesym = re.compile(r'^([A-Za-z_?@.][A-Za-z0-9_?@.$]*)'
    r'\s+EQU\s+0([0-9A-F]{4})H$')
  kind = sys.argv[1].lower()
  sym = {}
  f = open('vdptest%s.sym' % kind[0], 'r')
  try:
    for line in f:
      g = parsesym.search(line)
      if g:
        r = Val(int(g.group(2), 16))
        assert g.group(0) not in sym
        sym[g.group(1)] = r
  finally:
    f.close()

  fname = fnames[kind]

  # Deal with the line breaks as inserted by Python in this .py source file
  prg = template.replace('\r\n','\n').replace('\r','\n').replace('\n','\r\n')

  AckTiming = sym['AckTiming'].s
  sym['Start-1'] = Val(sym['Start'].s-1)
  sym['AckTiming+1'] = Val(AckTiming+1)
  sym['AckTiming+2'] = Val(AckTiming+2)
  sym['AckTiming+3'] = Val(AckTiming+3)
  prg = prg.format(sym=sym, filename=fname)
  sys.stdout.buffer.write(prg.encode('latin1'))

main()
